package com.cskaoyan.javase.string._6comparator;

import java.util.Arrays;
import java.util.Comparator;

/**
 * 带比较器的排序方法
 *      Arrays.sort(arr,Comparator)
 *      Collections.sort(collection,Comparator)
 *
 * Comparator接口中的抽象方法是: compare方法
 * int compare(T o1, T o2);
 * 该方法来表示一个比较的规则,这个比较的规则,可以在调用方法时灵活的传入,相比较于Comparable接口,灵活性大大提升
 *
 * Comparator接口中的compare(Object o1,Object o2)方法表示一种排序规则，使用起来可以看成o1 - o2：
 *      1.方法返回负数，表示o1小于o2，排序时o1处在前列。
 *      2.方法返回正数，表示o1大于o2，排序时o2小，处在前列。
 *      3.方法返回0，表示o1等于o2，排序时按照原本的位置排列在一起。
 *
 *
 * @since 16:32
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student[] stus = new Student[10];
        stus[0] = new Student(10, "三", 100);
        stus[1] = new Student(18, "马云云123", 70);
        stus[2] = new Student(20, "张晓宇", 30);
        stus[3] = new Student(7, "刘华强2", 10);
        stus[4] = new Student(7, "A", 60);
        stus[5] = new Student(7, "A", 65);
        stus[6] = new Student(10, "A", 20);
        stus[7] = new Student(20, "ABC", 30);
        stus[8] = new Student(10, "A", 90);
        stus[9] = new Student(10, "A", 7);

        Arrays.sort(stus, new SortRuler());
        for (Student s : stus) {
            System.out.println(s);
        }

        System.out.println("-----------------------");

        // 排序规则2: 成绩由低到高排序  匿名内部类来创建接口的实现类对象
        Arrays.sort(stus, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 站在o1的角度思考,成绩越低,对象越小,方法就越返回一个负数,排序就越在前面
                return (int) (o1.score - o2.score);
            }
        });
        for (Student s : stus) {
            System.out.println(s);
        }

        // 排序规则3: 按照名字的长度由短到长排序 用Lambda表达式
        // 站在s1角度思考,名字越长,对象越大,该方法就越要返回正数
        Arrays.sort(stus, (s1, s2) -> s1.name.length() - s2.name.length());

        System.out.println("----------------------");
        for (Student s : stus) {
            System.out.println(s);
        }

        System.out.println("----------------------");
        // 实现排序规则4
        // Arrays.sort(stus, (s1, s2) -> myCompare(s1, s2));
        Arrays.sort(stus, Demo::myCompare);
        for (Student s : stus) {
            System.out.println(s);
        }
    }

    public static int myCompare(Student s1, Student s2) {
        // 排序规则4: 先按照年龄从小到大进行排序,如果年龄一致,再按照名字的长度从短到长排序,其中如果名字长度一致,最后按照成绩由高到底排序
        if (s1.age != s2.age) {
            return s1.age - s2.age;
        }
        // 代码执行到这里,说明对象年龄一致,接下来根据名字的长度排序
        if (s1.name.length() != s2.name.length()) {
            return s1.name.length() - s2.name.length();
        }
        // 代码执行到这里,说明年龄相同,名字长度也相同,这时按照成绩排序
        return (int) (s2.score - s1.score);
    }
}

class SortRuler implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        // 排序规则1: 年龄从小到大排序
        // 我们把自己想象成o1,年龄越小,对象越小,o1-o2就越应该返回负数
        return o1.age - o2.age;
    }
}

class Student {
    int age;
    String name;
    double score;

    public Student(int age, String name, double score) {
        this.age = age;
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}